/**
 * File: DelegatingChannelFactory.java
 * Created by: mhaimel
 * Created on: 10 Aug 2009
 * CVS:  $Id: DelegatingChannelFactory.java,v 1.3 2009/12/07 10:10:32 mhaimel Exp $
 */
package uk.ac.ebi.curtain.util.file.impl;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.pool.KeyedPoolableObjectFactory;

import uk.ac.ebi.curtain.utils.CurtainUncheckedException;

/**
 * @author mhaimel
 *
 */
public class DelegatingChannelFactory implements KeyedPoolableObjectFactory {
	private final ChannelFactory[] facArr;
	
	public DelegatingChannelFactory(boolean read) {
		if(read){
			facArr = new ChannelFactory[]{
					new BufferedRafChannelFactory(),
					new BufferedReaderChannelFactory()
					};
		} else {
			facArr = new ChannelFactory[]{
					new PrintWriteChannelFactory(),
					new OutputStreamChannelFactory(),
					new WriteableByteChannelFactory()
					};
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public void activateObject(Object fin, Object cIn) throws Exception {
		getFactoryFromType(fin).activateObject(fin,cIn);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void destroyObject(Object fin, Object cIn) throws Exception {
		getFactoryFromType(fin).destroyObject(fin,cIn);
	}

	/**
	 * {@inheritDoc}
	 */
	public Object makeObject(Object fin) throws Exception {
		return getFactoryFromType(fin).makeObject(fin);
	}

	/**
	 * {@inheritDoc}
	 */
	public void passivateObject(Object fin, Object cin) throws Exception {
		getFactoryFromType(fin).passivateObject(fin, cin);
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean validateObject(Object fin, Object cin) {
		return getFactoryFromType(fin).validateObject(fin, cin);
	}
	
	private ChannelFactory getFactoryFromType(Object fin){
		FilePoolInfo info = getInfo(fin);
		ChannelFactory fac = null;
		for(ChannelFactory curr : facArr){
			if(curr.getType().equals(info.getType())){
				fac=curr;
				break;
			}
		}
		if(null == fac){
			throw new CurtainUncheckedException("Channel type not supported: " + info + " in " + StringUtils.join(facArr,';'));
		}
		return fac;
	}

	private FilePoolInfo getInfo(Object fileInfo){
		return (FilePoolInfo) fileInfo;
	}

}
